﻿///==========================================================================
///                               ===InputHandler.cs===
///Wraps user input into a class allowing checks to be performed on
///multiple input devices with a single method call.
///==========================================================================
///Original Author:  Jonathan Deaves ("garfunkle")
///Date:    27-March-2011
///Version: 1.1(Light)
///==========================================================================
///Usage:
///1. Declare an InputHandler instance at top of class that will receive input
///   E.G. InputHandler inputHandle;
///2. Initalize it somewhere (usually in an init method of some kind)
///   E.G inputHandle = new InputHandler();
///3. Call it's update during the class update, before any input.
///   E.G inputHandle.Update();
///3. Then call individual methods to check keys.
///   E.G.
///   if(inputHandle.isKeyDown(Microsoft.Xna.Framework.Input.Keys.Down)){
///       Player.Position.Y++;
///   }
///   This example will check if the Down key of keyboard is pressed.
///4. This default script comes with several methods which are commented for
///   their functions. Use them as a base for extending the function to your
///   personal project.
///==========================================================================
///Edited by:     Joel Daignault
///Date:          18-November-2011
///Last Modified: 30-March-2012
///Version:       1.5
///==========================================================================

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace TLib.Xna
{
    public class InputHandler
    {
        /// <summary>
        /// These store current and previous states
        /// of input devices supported.
        /// </summary>
        private KeyboardState keyboardState;
        private KeyboardState previousKeyboardState;
        private MouseState mouseState;
        private MouseState previousMouseState;

        /// <summary>
        /// Creates a new InputHandler object.
        /// </summary>
        public InputHandler() { }

        /// <summary>
        /// Updates the input states.
        /// </summary>
        public void Update()
        {
            //Sets previous states to that of what was just pressed.
            previousKeyboardState = keyboardState;
            previousMouseState = mouseState;

            //Updates current states to current presses
            keyboardState = Keyboard.GetState();
            mouseState = Mouse.GetState();
        }

        #region Keyboard
        /// <summary>
        /// Returns whether a key has just been pressed.
        /// </summary>
        /// <param name="key">The key on the keyboard to be evaluated.</param>
        public bool isKeyDownNew(Keys key)
        {
            return (keyboardState.IsKeyDown(key) && 
                    previousKeyboardState.IsKeyUp(key));
        }

        /// <summary>
        /// Returns whether a key is currently being pressed.
        /// </summary>
        /// <param name="key">The key on the keyboard to be evaluated.</param>
        public bool isKeyDown(Keys key)
        {
            return keyboardState.IsKeyDown(key);
        }

        /// <summary>
        /// Returns whether a key has just been released.
        /// </summary>
        /// <param name="key">The key on the keyboard to be evaluated.</param>
        public bool isKeyUpNew(Keys key)
        {
            return (keyboardState.IsKeyUp(key) &&
                    previousKeyboardState.IsKeyDown(key));
        }

        /// <summary>
        /// Returns whether a key is currently not being pressed.
        /// </summary>
        /// <param name="key">The key on the keyboard to be evaluated.</param>
        public bool isKeyUp(Keys key)
        {
            return keyboardState.IsKeyUp(key);
        }
        #endregion

        #region Mouse
        /// <summary>
        /// Gets or sets the position of the Mouse pointer in the client window.
        /// </summary>
        public Vector2 MousePosition
        {
            get { return new Vector2(mouseState.X, mouseState.Y); }
            set
            {
                Mouse.SetPosition((int)value.X, (int)value.Y);
                mouseState = Mouse.GetState();
            }
        }

        /// <summary>
        /// Gets or sets the window used for Mouse processing.
        /// </summary>
        public System.IntPtr MouseWindowHandle
        {
            get { return Mouse.WindowHandle; }
            set { Mouse.WindowHandle = value; }
        }

        /// <summary>
        /// Returns the movement vector of the mouse since last update.
        /// </summary>
        public Vector2 MouseMoveVector()
        {
            return (new Vector2(mouseState.X - previousMouseState.X, mouseState.Y - previousMouseState.Y));
        }

        /// <summary>
        /// Returns whether the left mouse button has just been pressed.
        /// </summary>
        public bool isMouseLeftDownNew()
        {
            return (mouseState.LeftButton == ButtonState.Pressed && previousMouseState.LeftButton == ButtonState.Released);
        }

        /// <summary>
        /// Returns whether the left mouse button is currently being pressed.
        /// </summary>
        public bool isMouseLeftDown()
        {
            return (mouseState.LeftButton == ButtonState.Pressed);
        }

        /// <summary>
        /// Returns whether the left mouse button has just been released.
        /// </summary>
        public bool isMouseLeftUpNew()
        {
            return (mouseState.LeftButton == ButtonState.Released && previousMouseState.LeftButton == ButtonState.Pressed);
        }

        /// <summary>
        /// Returns whether the left mouse button is currently not being pressed.
        /// </summary>
        public bool isMouseLeftUp()
        {
            return (mouseState.LeftButton == ButtonState.Released);
        }

        /// <summary>
        /// Returns whether the right mouse button has just been pressed.
        /// </summary>
        public bool isMouseRightDownNew()
        {
            return (mouseState.RightButton == ButtonState.Pressed && previousMouseState.RightButton == ButtonState.Released);
        }

        /// <summary>
        /// Returns whether the right mouse button is currently being pressed.
        /// </summary>
        public bool isMouseRightDown()
        {
            return (mouseState.RightButton == ButtonState.Pressed);
        }

        /// <summary>
        /// Returns whether the right mouse button has just been released.
        /// </summary>
        public bool isMouseRightUpNew()
        {
            return (mouseState.RightButton == ButtonState.Released && previousMouseState.RightButton == ButtonState.Pressed) ;
        }

        /// <summary>
        /// Returns whether the right mouse button is currently not being pressed.
        /// </summary>
        public bool isMouseRightUp()
        {
            return (mouseState.RightButton == ButtonState.Released) ;
        }

        /// <summary>
        /// Returns whether the scroll wheel has been moved forward.
        /// </summary>
        public bool isMouseScrollUp()
        {
            return (mouseState.ScrollWheelValue > previousMouseState.ScrollWheelValue) ;
        }

        /// <summary>
        /// Returns whether the scroll wheel has been moved backward.
        /// </summary>
        public bool isMouseScrollDown()
        {
            return (mouseState.ScrollWheelValue < previousMouseState.ScrollWheelValue) ;
        }
        #endregion
    }
}